<!-- 首页 -->
<template>
	<view>
		<!-- #ifdef MP -->
		<uni-nav-bar :shadow="false" :border="false" @clickLeft="clickLeft" @clickRight="clickRight">
			<!-- 左边图标 -->
			<block slot="left">
				<view class="iconfont icon-qiandao ml-2 mr-2" style="font-size: 22px;color: #FF9619;"></view>
			</block>
			<!-- 中间搜索框 -->
			<view
				class="flex justify-center align-center rounded text-muted bg-light flex-1 mt-1"
				style="margin-left: -46upx;height: 60upx;"
				@tap="openSearch"
			>
				<view class="iconfont icon-sousuo mr-1"></view>搜索帖子
			</view>
			<!-- 右边图标 -->
			<block slot="right">
				<view class="icon iconfont icon-fatie_icon text-dark" style="font-size: 22px;"></view>
			</block>
		</uni-nav-bar>
		<!-- #endif -->
		<!-- 顶部选项卡 --------------------------------------------- -->
		<scroll-view scroll-x :scroll-into-view="scrollInto" class="scroll-row" style="height: 100rpx;">
			<!-- 给每个子元素添加一个id，非常核心！！！ -->
			<view
				v-for="(item, index) in tabBars"
				:key="index"
				:id="'tab' + index"
				class="scroll-row-item px-5 py-3 font-md"
				:class="tabIndex === index ? 'text-main font-lg font-weight-bold' : ''"
				@click="changeTab(index)"
			>
				{{ item.classname }}
			</view>
		</scroll-view>
		<!-- 引入 全局分割线 组件 --------------------------------------------- -->
		<DividerLine></DividerLine>
		<!-- 分类详情 -->
		<swiper :duration="300" :current="tabIndex" @change="onChangeTab" :style="'height:' + scrollH + 'px;'">
			<!-- 监听当前列表的 触底事件 @scrolltolower-->
			<swiper-item v-for="(item, index) in newsList" :key="index">
				<scroll-view scroll-y="true" :style="'height:' + scrollH + 'px;'" @scrolltolower="loadmore(index)">
					<!-- 有数据时 展示 -->
					<template v-if="item.list.length > 0">
						<!-- 测试滚动区域 -->
						<!-- <view v-for="i in 100" :key="i">{{i}}</view> -->
						<block v-for="(itemL, indexL) in item.list" :key="indexL">
							<!-- 引入 封装的 列表组件
						定义自定义事件，接收子组件，发布的follow事件 -->
							<commonList :item="itemL" :index="indexL" @follow="follow" @doSupport="doSupport">
							</commonList>
							<!-- 引入 全局分割线 组件 -->
							<DividerLine></DividerLine>
						</block>

						<!-- 上拉加载 -->
						<loadMore :loadmore="item.loadmore"></loadMore>
					</template>
					<!-- --------------------------------------------- -->
					<!-- 加载中 -->
					<template v-else-if="!item.firstLoad">
						<uni-load-more
							iconType="circle"
							showIcon
							status="loading"
							showText
							:content-text="contentText"
						/>
					</template>
					<!-- 无数据时 -->
					<template v-else>
						<noThing></noThing>
					</template>
				</scroll-view>
			</swiper-item>
		</swiper>
	</view>
</template>

<script>
	// 引入封装的列表数据 模块
	import commonList from '@/components/common/common-list.vue';
	// 引入上拉更多 组件
	import loadMore from '@/components/common/load-more.vue';
	// 引入 兜底样式 组件
	import noThing from '@/components/common/no-thing.vue';
	export default {
		// 注册引入的组件
		components: {
			commonList,
			loadMore,
			noThing,
		},
		data() {
			return {
				// 列表高度
				scrollH: 600,
				// 顶部选项卡
				scrollInto: '', // 滚动到指定元素
				tabIndex: 0, // 默认选中第一个，并添加粉红色样式
				// 顶部选项卡数据
				tabBars: [],
				// 列表数据
				newsList: [],
				contentText: {
					contentrefresh: '加载中...',
				},
			};
		},
		// 监听点击 导航栏搜索框 ---------------------------------------
		onNavigationBarSearchInputClicked() {
			// 保留当前页面，跳转到应用内的某个页面（相当于生成一个新页面)
			uni.navigateTo({
				// ?type=post 搜索帖子
				url: '../search/search?type=post',
			});
		},
		// 监听导航按钮 事件
		onNavigationBarButtonTap() {
			// 将uni替换为 this，调用挂载在原型的 权限跳转页面验证
			this.navigateTo({
				// 跳转到 发布页面
				url: '../add-input/add-input',
			});
		},
		// 监听页面加载 -----------------------------------------------
		onLoad() {
			// 异步获取 系统信息
			uni.getSystemInfo({
				success: (res) => {
					// console.log(res); 将rpx转换为px 使用uni.upx2px()
					//  减去 顶部选项卡的高度
					this.scrollH = res.windowHeight - uni.upx2px(107);
					// console.log(this.scrollH);
					// #ifdef MP
					this.scrollH -= 44;
					// #endif
				},
			});
			// 根据选项生成列表
			this.getData();
			// 监听刷新首页
			uni.$on('updateIndex', () => {
				this.getData();
			});
			// 监听common-list组件 关注和顶踩
			uni.$on('updateFollSupport', (e) => {
				switch (e.type) {
					case 'follow': // 关注
						this.follow(e.data.user_id);
						break;
					case 'support': // 顶踩 操作
						this.doSupport(e.data);
						break;
				}
			});
			// 监听评论数变化
			uni.$on('updateComments', ({ id, count }) => {
				// 查询所有分类
				this.newsList.forEach((tab) => {
					// 查询 分类下的所有列表
					tab.list.forEach((item) => {
						// 查询到 此篇帖子 id
						if (item.id === id) {
							// 动态修改评论数
							item.comment_count = count;
						}
					});
				});
			});
		},
		// 页面卸载 时
		onUnload() {
			// 清除 监听事件
			uni.$off('updateFollSupport', (e) => {});
			uni.$off('updateIndex', (e) => {});
			uni.$off('updateComments', (e) => {});
		},
		methods: {
			// #ifndef APP-PLUS
			clickLeft() {
				// console.log('左边事件')
			},
			clickRight() {
				// 打开发布页面
				this.navigateTo({
					url: '../add-input/add-input',
				});
			},
			openSearch() {
				uni.navigateTo({
					url: '../search/search',
				});
			},
			// #endif
			// 获取 分类数据 -------------------------------------------
			getData() {
				// 请求 顶部选项卡 接口
			   this.$H.get('/postclass').then(res=>{
				// 赋值顶部选项卡
				this.tabBars = res.list;

				// 根据 分类 生成列表
				// 存放 循环好的，列表数据
				const arr = [];
				// 循环遍历 顶部选项卡数据
				// 根据多少个选项 生成多少个模版 ，再赋值给列表数据newsList
				for (let i = 0; i < this.tabBars.length; i++) {
					// 生成列表模版数据
					arr.push({
						// 三种状态 1. 上拉加载更多 2. 加载中... 3. 没有更多了
						loadmore: '上拉加载更多',
						list: [], // 列表数据
						page: 1, // 分页
						// 用于判断，列表数据是否 重复加载
						firstLoad: false,
					});
				}
				this.newsList = arr;
				// 获取第一个 分类列表 的数据
				if (this.tabBars.length) {
					this.getList();
				}
			  })
			},
			// 获取 指定分类 下的列表数据 ---------------------------------
			getList() {
				//  获取到当前 分类的 下标
				let index = this.tabIndex;
				// 获取指定分类 的 ID
				let id = this.tabBars[index].id;
				// 获取指定 列表数据 的 页数
				let page = this.newsList[index].page;
				// 判断 是否处于 第一页 列表数据（如果是就是用户在刷新，否则追加数据）
				let isRefresh = page === 1;

				// 获取 指定文章分类下的文章列表 接口请求
				this.$H
					.get(
						'/postclass/' + id + '/post/' + page,
						{},
						{
							token: true,
							noCheck: true, // 不去验证token，接口不需要传token
						},
					)
					.then((res) => {
						// 循环获取到，指定的列表数据，要循环遍历一下
						let list = res.list.map((v) => {
							// 调用 封装的 工具类utils.js中，转换列表数据方法
							return this.$U.forMatCommonList(v);
						});
						// console.log(resultL);
						/* 根据获取到 指定id分类，赋值列表数据 
					   判断 是否处于 第一页 列表数据
					  （如果是 那用户正在刷新页面，否则追加数据）
					   加载更多[当前页数据，下一页数据]*/
						this.newsList[index].list = isRefresh ? list : [...this.newsList[index].list, ...list];
						/* 如果当前 列表数据<10条 ，展示'没有更多了'否则‘下拉加载更多’*/
						this.newsList[index].loadmore = list.length < 10 ? '没有更多了' : '上拉加载更多';
						// 判断是否 重复加载列表数据
						if (isRefresh) {
							this.newsList[index].firstLoad = true;
						}
					})
					.catch((err) => {
						// 如果未获取到数据
						if (!isRefresh) {
							// 如果不是刷新的情况下，退回上一页
							this.newsList[index].page--;
						}
					});
			},
			// 监听swiper滑动 ----------------------------------------
			onChangeTab(e) {
				// 分类列表滑动，顶部选项卡跟随切换
				this.changeTab(e.detail.current);
			},
			// 顶部选项卡（切换选项）------------------------------------
			changeTab(index) {
				// 如果点击的选项 全等于 自己，终止进程
				if (this.tabIndex === index) return;
				// 否则切换选项
				this.tabIndex = index;
				// 滚动到指定元素（必须和指定，的子元素id相同)
				this.scrollInto = 'tab' + index;
				/* 判断 首次加载列表数据成功，变为true, (防止重复加载) false就是未请求过*/
				if (!this.newsList[this.tabIndex].firstLoad) {
					// 获取 当前分类下的 列表数据
					this.getList();
				}
			},
			// 关注 -------------------------------------------------
			// 使用自定义事件 follow 关注
			follow(user_id) {
				/* 找到 当前作者的 所有列表数据
				1.遍历所有 分类tab */
				this.newsList.forEach((tab) => {
					// 查询 所有分类 tab 下面的list列表数据
					tab.list.forEach((item) => {
						// 当前点击的用户下的 isFollow (改为true，隐藏关注)
						if (item.user_id === user_id) {
							item.isFollow = !item.isFollow;
						}
					});
				});
			},
			// 顶 或 踩 （操作）---------------------------------------
			doSupport(e) {
				// 拿到 当前的分类选项卡 对应的list列表数据
				this.newsList[this.tabIndex].list.forEach((item) => {
					// 拿到 每一条 帖子的id
					// 如果列表数据id 和 顶踩 操作id一致
					if (item.id === e.id) {
						// console.log('顶踩操作',item);
						// 判断之前是否已经 赞 或踩 (之前未操作)
						if (item.support.type === '') {
							/* 4. 点击当前 赞 或 踩 数量+1
							 子组件通过 support 判断样式添加，这里需要拼接子组件发布的type值，点击哪一个就让 此 +1 */
							item.support[e.type + '_count']++;
						} else if (item.support.type === 'support' && e.type === 'unsupport') {
							// 如果之前 赞了（判断原数据是赞的，并且 现在点击了 踩）
							// 赞 -1
							item.support.support_count--;
							// 踩 +1
							item.support.unsupport_count++;
						} else if (item.support.type === 'unsupport' && e.type === 'support') {
							// 如果之前 踩了（判断原数据是踩的，并且 现在点击了 赞）
							// 赞 +1
							item.support.support_count++;
							// 踩 -1
							item.support.unsupport_count--;
						}
						/* 2. 赋值给，子组件发布的type（赞 或踩）
						   3. 子组件 通过type 判断 添加样式 或 事件 */
						item.support.type = e.type;
					}
				});
				// 消息提示
				let msg = e.type === 'support' ? '点赞成功' : '踩一脚';
				uni.showToast({ title: msg,icon:'none', duration: 500 });
			},
			// 上拉加载更多 ，监听事件 ----------------------------------
			loadmore(index) {
				// 先拿到当前列表
				let item = this.newsList[index];
				// 判断是否处于可加载状态（上拉加载更多) 只请求一次接口
				if (item.loadmore !== '上拉加载更多') return;
				// 修改当前列表加载状态
				item.loadmore = '加载中...';

				/* 请求 指定分类 下的列表数据
				   展示下一页，要让 当前页数++ */
				item.page++;
				setTimeout(() => {
					this.getList();
				}, 2000);
			},
		},
	};
</script>

<style lang="scss" scoped></style>
